package cn.com.linht.jsontosql.entity;

import cn.com.linht.jsontosql.enums.TypeEnum;
import cn.com.linht.jsontosql.util.Assert;
import net.sf.jsqlparser.util.validation.Validation;
import net.sf.jsqlparser.util.validation.ValidationError;
import net.sf.jsqlparser.util.validation.feature.DatabaseType;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.collections4.MapUtils;
import org.apache.commons.lang3.StringUtils;

import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 算子，连接方式等
 *
 * @author linht
 */
public class OperatorVO {
    private String id;
    private String name;
    private List<String> input;
    private String sqlScript;
    private TypeEnum type;

    /**
     * 整个查询的过滤条件
     */
    private List<QueryCriteriaVO> queryCriteriaList;

    public List<QueryCriteriaVO> getQueryCriteriaList() {
        return queryCriteriaList;
    }

    public void setQueryCriteriaList(List<QueryCriteriaVO> queryCriteriaList) {
        this.queryCriteriaList = queryCriteriaList;
    }

    public String getId() {
        return id;
    }

    public void setId(String id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public List<String> getInput() {
        return input;
    }

    public void setInput(List<String> input) {
        this.input = input;
    }

    public String getSqlScript() {
        return sqlScript;
    }

    public void setSqlScript(String sqlScript) {
        this.sqlScript = sqlScript;
    }

    public TypeEnum getType() {
        return type;
    }

    public void setType(TypeEnum type) {
        this.type = type;
    }

    @Override
    public String toString() {
        return "OperatorVO{" +
                "id='" + id + '\'' +
                ", name='" + name + '\'' +
                ", input=" + input +
                ", sqlScript='" + sqlScript + '\'' +
                ", type=" + type +
                ", queryCriteriaList=" + queryCriteriaList +
                '}';
    }

    /***
     * 将list的id遍历输出
     * @param list
     * @return
     */
    public static List<String> getIdList(List<OperatorVO> list) {
        Assert.isTrue(CollectionUtils.isNotEmpty(list), "算子集合不能为空或null");
        return list.stream().map(OperatorVO::getId).collect(Collectors.toList());
    }

    public static boolean checkIdIsExistsList(String id, List<OperatorVO> list) {
        Assert.isTrue(StringUtils.isNotBlank(id), "id为空");
        return getIdList(list).contains(id);
    }


    /**
     * 1、 将其转换成sql
     * 2、替换掉本算子的过滤条件
     *
     * @return
     */
    public String transformSql(Map<String, String> tables) {
        String sql = sqlScript;

        for (String e : input) {
            String replacement = tables.get(e);
            sql = sql.replaceAll(e, replacement);
        }
        Map<String, Object> filter = QueryCriteriaVO.listToMap(this.queryCriteriaList);
        sql = fillFilter(sql, filter);
        return sql;
    }


    /***
     * 填充占位符
     * @param sql
     * @return
     */
    public static String fillFilter(String sql, Map<String, Object> filter) {
        for (String o : filter.keySet()) {
            sql = sql.replaceAll("#\\{" + o + "\\}", MapUtils.getString(filter, o));
        }
        return sql;
    }

    /**
     * 校验输入里是否包含在table集合中
     *
     * @param tables
     * @return
     */
    public boolean containsKey(Map<String, String> tables) {
        Assert.isTrue(CollectionUtils.isNotEmpty(input), "算子id为" + id + "的输出为空");
        for (String e : input) {
            if (!tables.containsKey(e)) {
                return false;
            }
        }
        return true;
    }
}
